'''
Created on 23.2.2011.

@author: Ana Banana
'''
from xml.dom.expatbuilder import TEXT_NODE

'''
Created on Nov 14, 2010

@author: daenerys
'''

import re
import xml.dom.minidom
from loading.xmlparser.network import Node
from loading.xmlparser.network import Edge
from loading.xmlparser import IDUtil

class XMLoader:
    
    def getText(self, nodelist):
        rc = []
        for node in nodelist:
            if node.nodeType == node.TEXT_NODE:
                rc.append(node.data)
        return ''.join(rc)

    def __init__(self, ppi_file, net):
        self.ppi_file = ppi_file   
        self.net = net     
        
    def loadFile (self, file_name):
        file = open (file_name, 'r');
        self.ppi_file = xml.dom.minidom.parseString (file.read())
    
    def handlePPI (self):
        self.nodes = self.ppi_file.getElementsByTagName('interactor')
        self.handleNodes ()
        self.edges = self.ppi_file.getElementsByTagName('interaction')
        self.handleEdges()
        
    def handleNodes (self):
        id = 0;
        for interactor in self.nodes: #sad imam interactora:
            idRef = interactor.attributes.item(0).value;
            names =  interactor.getElementsByTagName("names")
            shL = names[0].getElementsByTagName("shortLabel");
            fN =  names[0].getElementsByTagName("fullName");
            if shL.length > 0: 
                shortLabel = self.getText(shL[0].childNodes);
            if fN.length > 0:
                fullName = self.getText(fN[0].childNodes);
            
            org = interactor.getElementsByTagName("organism")[0];
            ncbiTaxId = org.attributes.item(0).value;
            
            xref = interactor.getElementsByTagName("xref")[0]
            primRef = xref.getElementsByTagName("primaryRef")[0];
            secRef = xref.getElementsByTagName("secondaryRef");
            
            #searching for primary id
            for i in range(primRef.attributes.length):
                id_uniprot = "";
                id_entrez = "";
                id_refseq = "";
                atr = primRef.attributes.item(i);
                if (atr.name == "id"):
                    id_dip =  atr.value;
            if secRef.length > 0:
                #secRef = secRef[1];
                for secR in secRef:
                    for i in range(secR.attributes.length):
    
                        atr = secR.attributes.item(i);
                        if (atr.value == "uniprot knowledge base"):
                            for j in range(secR.attributes.length):
                                attr = secR.attributes.item(j);
                                if(attr.name == "id"):
                                    id_uniprot = attr.value
                        
                        if (atr.value == "entrez gene/locuslink"):
                            for j in range(secR.attributes.length):
                                attr = secR.attributes.item(j);
                                if(attr.name == "id"):
                                    id_entrez = attr.value
                        
                    
                        if (atr.value == "refseq"):
                            for j in range(secR.attributes.length):
                                attr = secR.attributes.item(j);
                                if(attr.name == "id"):
                                    id_refseq = attr.value
                        
                        
            if re.match("PREDICTED.*", fullName) or re.match("similar.*", fullName):
                continue;
            if ncbiTaxId == "-2":
                sequence = interactor.getElementsByTagName("sequence")[0];
                id_uniprot = self.getText(sequence.childNodes);
            elif id_uniprot == "":
                id_uniprot = self.getNodeUniprotId(fullName, ncbiTaxId);
                #ako se id ne more naci niti u uniprot bazi, preskacemo ga
                if id_uniprot == "":
                    continue;
            #print "%s\t%s" % (fullName, id_uniprot)
            n = Node.Node(id, idRef, shortLabel, fullName, id_dip, id_uniprot, id_entrez, ncbiTaxId);
            self.net.addNode(n);
            id = id+1;
            #print "%s\t%s\t%s" % (id, shortLabel, fullName)
            #print "%s\t%s\t%s\t%s" % (id_dip, id_uniprot, id_entrez, id_refseq)
                                    
            #print "\n\n\n"
                    
                
           
    def getNodeUniprotId (self, fullname, taxid):
        while re.match(".*\)$", fullname):
            name = re.match("(.*)\(.*\)$", fullname);
            fullname = name.group(1)   
        desc = fullname + ' ' + taxid;
        id_uniprot = IDUtil.uniprot_id(desc);
        return id_uniprot
            

    def handleEdges (self):
        id = 0;
        for interaction in self.edges:
            parL = interaction.getElementsByTagName("participantList")[0];
            parts = parL.getElementsByTagName("participant");
            if parts.length != 2:
                continue
            id1 = parts[0].getElementsByTagName("interactorRef")[0];
            idRef1 = self.getText(id1.childNodes);
            id2 = parts[1].getElementsByTagName("interactorRef")[0];
            idRef2 = self.getText(id2.childNodes);
            e = Edge.Edge(id, idRef1, idRef2);
            if not self.net.nodes.has_key(idRef1) or not self.net.nodes.has_key(idRef2):
                print "\nHas no node %s or %s, deleting edge\n" % (idRef1, idRef2);
                continue;
            self.net.addEdge(e);
            id = id+1;
                    

